//! # 安全审计功能测试
//!
//! 测试企业级安全审计功能的完整性和正确性

use std::sync::Arc;
use std::collections::HashMap;
use tokio;
use rustcloud_auth::prelude::*;

#[cfg(feature = "audit")]
use rustcloud_auth::audit::{
    SecurityAuditor, SecurityEvent, SecurityEventType, AuthEventType, AuthzEventType,
    EventResult, AuditConfig, AuditStorageType, ComplianceReporter, AuditQuery, EventFilter
};

#[cfg(feature = "audit")]
mod audit_tests {
    use super::*;
    use std::time::{SystemTime, Duration};

    /// 测试基础审计功能
    #[tokio::test]
    async fn test_basic_audit_functionality() {
        let config = AuditConfig::default();
        let auditor = crate::audit::SecurityAuditor::new(config).await.unwrap();

        // 创建测试事件
        let auth_event = SecurityEvent {
            id: "test_auth_001".to_string(),
            timestamp: SystemTime::now(),
            event_type: SecurityEventType::Authentication(AuthEventType::Login),
            principal_id: Some("test_user".to_string()),
            resource: Some("auth-service".to_string()),
            action: Some("login".to_string()),
            result: EventResult::Success,
            client_ip: Some("192.168.1.100".to_string()),
            user_agent: Some("Test Client 1.0".to_string()),
            session_id: Some("session_123".to_string()),
            additional_data: HashMap::new(),
            risk_score: Some(1), // 低风险
        };

        // 记录事件
        let result = auditor.log_event(auth_event.clone()).await;
        assert!(result.is_ok());

        // 验证事件可以检索
        let query = AuditQuery {
            event_types: Some(vec![SecurityEventType::Authentication(AuthEventType::Login)]),
            principal_id: Some("test_user".to_string()),
            start_time: Some(SystemTime::now() - Duration::from_secs(60)),
            end_time: Some(SystemTime::now() + Duration::from_secs(60)),
            limit: Some(10),
            offset: Some(0),
        };

        let events = auditor.query_events(query).await.unwrap();
        assert!(!events.is_empty());
        assert_eq!(events[0].id, "test_auth_001");
    }

    /// 测试批量事件记录
    #[tokio::test]
    async fn test_batch_event_logging() {
        let config = AuditConfig::default();
        let auditor = crate::audit::SecurityAuditor::new(config).await.unwrap();

        let mut events = Vec::new();
        let base_time = SystemTime::now();

        // 创建多个测试事件
        for i in 0..10 {
            let event = SecurityEvent {
                id: format!("batch_test_{:03}", i),
                timestamp: base_time + Duration::from_secs(i),
                event_type: SecurityEventType::Authentication(AuthEventType::Login),
                principal_id: Some(format!("user_{}", i)),
                resource: Some("auth-service".to_string()),
                action: Some("login".to_string()),
                result: if i % 2 == 0 { EventResult::Success } else { EventResult::Failure },
                client_ip: Some(format!("192.168.1.{}", 100 + i)),
                user_agent: Some("Test Client 1.0".to_string()),
                session_id: Some(format!("session_{}", i)),
                additional_data: HashMap::new(),
                risk_score: Some(if i % 3 == 0 { 5 } else { 1 }),
            };
            events.push(event);
        }

        // 批量记录事件
        let result = auditor.log_events(events).await;
        assert!(result.is_ok());

        // 验证事件数量
        let query = AuditQuery {
            event_types: Some(vec![SecurityEventType::Authentication(AuthEventType::Login)]),
            start_time: Some(base_time - Duration::from_secs(10)),
            end_time: Some(base_time + Duration::from_secs(20)),
            limit: Some(20),
            offset: Some(0),
        };

        let retrieved_events = auditor.query_events(query).await.unwrap();
        assert!(retrieved_events.len() >= 10);
    }

    /// 测试认证事件审计
    #[tokio::test]
    async fn test_authentication_audit() {
        let config = AuditConfig::default();
        let auditor = crate::audit::SecurityAuditor::new(config).await.unwrap();

        // 成功登录事件
        let login_success = crate::audit::AuthenticationEvent {
            timestamp: SystemTime::now(),
            source_ip: Some("192.168.1.100".to_string()),
            user_agent: Some("Mozilla/5.0 Test".to_string()),
            method: "POST".to_string(),
            uri: "/api/auth/login".to_string(),
            success: true,
            error_message: None,
            user_id: Some("test_user".to_string()),
        };

        // 失败登录事件
        let login_failure = crate::audit::AuthenticationEvent {
            timestamp: SystemTime::now(),
            source_ip: Some("203.0.113.1".to_string()),
            user_agent: Some("Suspicious Client".to_string()),
            method: "POST".to_string(),
            uri: "/api/auth/login".to_string(),
            success: false,
            error_message: Some("Invalid credentials".to_string()),
            user_id: None,
        };

        // 记录认证事件
        let result1 = auditor.log_authentication(login_success).await;
        let result2 = auditor.log_authentication(login_failure).await;

        assert!(result1.is_ok());
        assert!(result2.is_ok());

        // 查询认证失败事件
        let query = AuditQuery {
            event_types: Some(vec![SecurityEventType::Authentication(AuthEventType::LoginFailure)]),
            start_time: Some(SystemTime::now() - Duration::from_secs(60)),
            end_time: Some(SystemTime::now() + Duration::from_secs(60)),
            limit: Some(10),
            offset: Some(0),
        };

        let failure_events = auditor.query_events(query).await.unwrap();
        assert!(!failure_events.is_empty());
        assert_eq!(failure_events[0].result, EventResult::Failure);
    }

    /// 测试授权事件审计
    #[tokio::test]
    async fn test_authorization_audit() {
        let config = AuditConfig::default();
        let auditor = crate::audit::SecurityAuditor::new(config).await.unwrap();

        // 授权成功事件
        let authz_success = crate::audit::AuthorizationEvent {
            timestamp: SystemTime::now(),
            user_id: "test_user".to_string(),
            resource_service: "blog-service".to_string(),
            resource_path: "/api/posts".to_string(),
            resource_action: "GET".to_string(),
            success: true,
            error_message: None,
        };

        // 授权失败事件
        let authz_failure = crate::audit::AuthorizationEvent {
            timestamp: SystemTime::now(),
            user_id: "test_user".to_string(),
            resource_service: "admin-service".to_string(),
            resource_path: "/api/admin/users".to_string(),
            resource_action: "DELETE".to_string(),
            success: false,
            error_message: Some("Insufficient permissions".to_string()),
        };

        // 记录授权事件
        let result1 = auditor.log_authorization(authz_success).await;
        let result2 = auditor.log_authorization(authz_failure).await;

        assert!(result1.is_ok());
        assert!(result2.is_ok());

        // 查询特定用户的授权事件
        let query = AuditQuery {
            principal_id: Some("test_user".to_string()),
            event_types: Some(vec![
                SecurityEventType::Authorization(AuthzEventType::AccessGranted),
                SecurityEventType::Authorization(AuthzEventType::AccessDenied),
            ]),
            start_time: Some(SystemTime::now() - Duration::from_secs(60)),
            end_time: Some(SystemTime::now() + Duration::from_secs(60)),
            limit: Some(10),
            offset: Some(0),
        };

        let authz_events = auditor.query_events(query).await.unwrap();
        assert!(authz_events.len() >= 2);
    }

    /// 测试安全事件过滤
    #[tokio::test]
    async fn test_event_filtering() {
        let config = AuditConfig::default();
        let auditor = crate::audit::SecurityAuditor::new(config).await.unwrap();

        let base_time = SystemTime::now();

        // 创建不同类型的事件
        let events = vec![
            SecurityEvent {
                id: "filter_test_001".to_string(),
                timestamp: base_time,
                event_type: SecurityEventType::Authentication(AuthEventType::Login),
                principal_id: Some("user1".to_string()),
                resource: Some("auth-service".to_string()),
                action: Some("login".to_string()),
                result: EventResult::Success,
                client_ip: Some("192.168.1.100".to_string()),
                user_agent: Some("Client 1.0".to_string()),
                session_id: Some("session_001".to_string()),
                additional_data: HashMap::new(),
                risk_score: Some(1),
            },
            SecurityEvent {
                id: "filter_test_002".to_string(),
                timestamp: base_time + Duration::from_secs(10),
                event_type: SecurityEventType::Authorization(AuthzEventType::AccessDenied),
                principal_id: Some("user2".to_string()),
                resource: Some("admin-service".to_string()),
                action: Some("delete".to_string()),
                result: EventResult::Failure,
                client_ip: Some("203.0.113.1".to_string()),
                user_agent: Some("Suspicious Client".to_string()),
                session_id: Some("session_002".to_string()),
                additional_data: HashMap::new(),
                risk_score: Some(8), // 高风险
            },
            SecurityEvent {
                id: "filter_test_003".to_string(),
                timestamp: base_time + Duration::from_secs(20),
                event_type: SecurityEventType::Authentication(AuthEventType::Logout),
                principal_id: Some("user1".to_string()),
                resource: Some("auth-service".to_string()),
                action: Some("logout".to_string()),
                result: EventResult::Success,
                client_ip: Some("192.168.1.100".to_string()),
                user_agent: Some("Client 1.0".to_string()),
                session_id: Some("session_001".to_string()),
                additional_data: HashMap::new(),
                risk_score: Some(1),
            },
        ];

        // 记录事件
        for event in events {
            auditor.log_event(event).await.unwrap();
        }

        // 测试按事件类型过滤
        let auth_query = AuditQuery {
            event_types: Some(vec![SecurityEventType::Authentication(AuthEventType::Login)]),
            start_time: Some(base_time - Duration::from_secs(10)),
            end_time: Some(base_time + Duration::from_secs(30)),
            limit: Some(10),
            offset: Some(0),
        };

        let auth_events = auditor.query_events(auth_query).await.unwrap();
        assert_eq!(auth_events.len(), 1);
        assert_eq!(auth_events[0].id, "filter_test_001");

        // 测试按用户过滤
        let user_query = AuditQuery {
            principal_id: Some("user2".to_string()),
            start_time: Some(base_time - Duration::from_secs(10)),
            end_time: Some(base_time + Duration::from_secs(30)),
            limit: Some(10),
            offset: Some(0),
        };

        let user_events = auditor.query_events(user_query).await.unwrap();
        assert_eq!(user_events.len(), 1);
        assert_eq!(user_events[0].principal_id, Some("user2".to_string()));

        // 测试按结果过滤
        let filter = EventFilter {
            result: Some(EventResult::Failure),
            min_risk_score: None,
            max_risk_score: None,
            client_ip_pattern: None,
        };

        let filtered_events = auditor.query_events_with_filter(
            base_time - Duration::from_secs(10),
            base_time + Duration::from_secs(30),
            Some(filter),
            10,
            0,
        ).await.unwrap();

        assert_eq!(filtered_events.len(), 1);
        assert_eq!(filtered_events[0].result, EventResult::Failure);
    }

    /// 测试高风险事件检测
    #[tokio::test]
    async fn test_high_risk_event_detection() {
        let config = AuditConfig::default();
        let auditor = crate::audit::SecurityAuditor::new(config).await.unwrap();

        // 创建高风险事件
        let high_risk_event = SecurityEvent {
            id: "high_risk_001".to_string(),
            timestamp: SystemTime::now(),
            event_type: SecurityEventType::Authentication(AuthEventType::LoginFailure),
            principal_id: None,
            resource: Some("auth-service".to_string()),
            action: Some("login".to_string()),
            result: EventResult::Failure,
            client_ip: Some("203.0.113.1".to_string()),
            user_agent: Some("Automated Bot".to_string()),
            session_id: None,
            additional_data: {
                let mut data = HashMap::new();
                data.insert("failed_attempts".to_string(), "10".to_string());
                data
            },
            risk_score: Some(9), // 非常高风险
        };

        // 记录高风险事件
        auditor.log_event(high_risk_event).await.unwrap();

        // 查询高风险事件
        let filter = EventFilter {
            result: None,
            min_risk_score: Some(8),
            max_risk_score: None,
            client_ip_pattern: None,
        };

        let high_risk_events = auditor.query_events_with_filter(
            SystemTime::now() - Duration::from_secs(60),
            SystemTime::now() + Duration::from_secs(60),
            Some(filter),
            10,
            0,
        ).await.unwrap();

        assert!(!high_risk_events.is_empty());
        assert!(high_risk_events[0].risk_score.unwrap_or(0) >= 8);
    }

    /// 测试合规性报告生成
    #[tokio::test]
    async fn test_compliance_reporting() {
        let config = AuditConfig::default();
        let auditor = crate::audit::SecurityAuditor::new(config).await.unwrap();

        let base_time = SystemTime::now();

        // 创建一系列测试事件
        let events = vec![
            // 成功登录
            SecurityEvent {
                id: "compliance_001".to_string(),
                timestamp: base_time,
                event_type: SecurityEventType::Authentication(AuthEventType::Login),
                principal_id: Some("admin_user".to_string()),
                resource: Some("auth-service".to_string()),
                action: Some("login".to_string()),
                result: EventResult::Success,
                client_ip: Some("192.168.1.10".to_string()),
                user_agent: Some("Admin Client".to_string()),
                session_id: Some("admin_session".to_string()),
                additional_data: HashMap::new(),
                risk_score: Some(2),
            },
            // 失败的管理员操作
            SecurityEvent {
                id: "compliance_002".to_string(),
                timestamp: base_time + Duration::from_secs(300),
                event_type: SecurityEventType::Authorization(AuthzEventType::AccessDenied),
                principal_id: Some("admin_user".to_string()),
                resource: Some("critical-service".to_string()),
                action: Some("delete_all".to_string()),
                result: EventResult::Failure,
                client_ip: Some("192.168.1.10".to_string()),
                user_agent: Some("Admin Client".to_string()),
                session_id: Some("admin_session".to_string()),
                additional_data: HashMap::new(),
                risk_score: Some(7),
            },
            // 成功注销
            SecurityEvent {
                id: "compliance_003".to_string(),
                timestamp: base_time + Duration::from_secs(600),
                event_type: SecurityEventType::Authentication(AuthEventType::Logout),
                principal_id: Some("admin_user".to_string()),
                resource: Some("auth-service".to_string()),
                action: Some("logout".to_string()),
                result: EventResult::Success,
                client_ip: Some("192.168.1.10".to_string()),
                user_agent: Some("Admin Client".to_string()),
                session_id: Some("admin_session".to_string()),
                additional_data: HashMap::new(),
                risk_score: Some(1),
            },
        ];

        // 记录事件
        for event in events {
            auditor.log_event(event).await.unwrap();
        }

        // 生成合规性报告
        let reporter = ComplianceReporter::new(Arc::new(auditor));
        let report = reporter.generate_activity_report(
            "admin_user",
            base_time - Duration::from_secs(60),
            base_time + Duration::from_secs(700),
        ).await.unwrap();

        // 验证报告内容
        assert_eq!(report.user_id, "admin_user");
        assert_eq!(report.total_events, 3);
        assert_eq!(report.successful_authentications, 1);
        assert_eq!(report.failed_authorizations, 1);
        assert_eq!(report.high_risk_events, 1); // risk_score >= 7
    }

    /// 测试数据保留策略
    #[tokio::test]
    async fn test_data_retention() {
        let mut config = AuditConfig::default();
        config.retention_days = 30; // 30天保留期

        let auditor = crate::audit::SecurityAuditor::new(config).await.unwrap();

        // 创建过期事件（超过保留期）
        let old_event = SecurityEvent {
            id: "old_event_001".to_string(),
            timestamp: SystemTime::now() - Duration::from_secs(32 * 24 * 3600), // 32天前
            event_type: SecurityEventType::Authentication(AuthEventType::Login),
            principal_id: Some("old_user".to_string()),
            resource: Some("auth-service".to_string()),
            action: Some("login".to_string()),
            result: EventResult::Success,
            client_ip: Some("192.168.1.200".to_string()),
            user_agent: Some("Old Client".to_string()),
            session_id: Some("old_session".to_string()),
            additional_data: HashMap::new(),
            risk_score: Some(1),
        };

        // 创建新事件（在保留期内）
        let new_event = SecurityEvent {
            id: "new_event_001".to_string(),
            timestamp: SystemTime::now() - Duration::from_secs(1 * 24 * 3600), // 1天前
            event_type: SecurityEventType::Authentication(AuthEventType::Login),
            principal_id: Some("new_user".to_string()),
            resource: Some("auth-service".to_string()),
            action: Some("login".to_string()),
            result: EventResult::Success,
            client_ip: Some("192.168.1.201".to_string()),
            user_agent: Some("New Client".to_string()),
            session_id: Some("new_session".to_string()),
            additional_data: HashMap::new(),
            risk_score: Some(1),
        };

        // 记录事件
        auditor.log_event(old_event).await.unwrap();
        auditor.log_event(new_event).await.unwrap();

        // 执行清理
        let cleanup_result = auditor.cleanup_old_events().await;
        assert!(cleanup_result.is_ok());

        // 验证新事件仍然存在
        let query = AuditQuery {
            principal_id: Some("new_user".to_string()),
            start_time: Some(SystemTime::now() - Duration::from_secs(2 * 24 * 3600)),
            end_time: Some(SystemTime::now()),
            limit: Some(10),
            offset: Some(0),
        };

        let new_events = auditor.query_events(query).await.unwrap();
        assert!(!new_events.is_empty());

        // 验证旧事件已被清理（这个测试在内存存储中可能不会真正删除，
        // 但在实际数据库实现中会删除）
        let old_query = AuditQuery {
            principal_id: Some("old_user".to_string()),
            start_time: Some(SystemTime::now() - Duration::from_secs(35 * 24 * 3600)),
            end_time: Some(SystemTime::now() - Duration::from_secs(30 * 24 * 3600)),
            limit: Some(10),
            offset: Some(0),
        };

        let old_events = auditor.query_events(old_query).await.unwrap();
        // 在内存实现中，事件可能仍然存在，但在数据库实现中应该被删除
    }

    /// 测试实时监控和告警
    #[tokio::test]
    async fn test_real_time_monitoring() {
        let config = AuditConfig::default();
        let auditor = crate::audit::SecurityAuditor::new(config).await.unwrap();

        // 模拟连续的失败登录尝试
        let base_time = SystemTime::now();
        let suspicious_ip = "203.0.113.100";

        for i in 0..5 {
            let event = SecurityEvent {
                id: format!("suspicious_{:03}", i),
                timestamp: base_time + Duration::from_secs(i * 10),
                event_type: SecurityEventType::Authentication(AuthEventType::LoginFailure),
                principal_id: None,
                resource: Some("auth-service".to_string()),
                action: Some("login".to_string()),
                result: EventResult::Failure,
                client_ip: Some(suspicious_ip.to_string()),
                user_agent: Some("Brute Force Tool".to_string()),
                session_id: None,
                additional_data: {
                    let mut data = HashMap::new();
                    data.insert("attempt_number".to_string(), (i + 1).to_string());
                    data
                },
                risk_score: Some(5 + i as i32), // 递增的风险分数
            };

            auditor.log_event(event).await.unwrap();
        }

        // 检测异常模式（同一IP的多次失败登录）
        let suspicious_events = auditor.detect_suspicious_activity(
            suspicious_ip,
            base_time - Duration::from_secs(60),
            base_time + Duration::from_secs(300),
        ).await.unwrap();

        assert!(suspicious_events.len() >= 5);
        assert!(suspicious_events.iter().all(|e| e.client_ip == Some(suspicious_ip.to_string())));
        assert!(suspicious_events.iter().all(|e| e.result == EventResult::Failure));

        // 验证风险分数递增
        for (i, event) in suspicious_events.iter().enumerate() {
            assert!(event.risk_score.unwrap_or(0) >= 5 + i as i32);
        }
    }
}